package main

import (
	"fmt"
	"io/fs"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/yourusername/gox/pkg/parser"
)

func main() {
	if len(os.Args) < 2 {
		log.Fatal("用法: goxgen <目录路径或文件路径>")
	}

	path := os.Args[1]

	// 检查是文件还是目录
	info, err := os.Stat(path)
	if err != nil {
		log.Fatal(err)
	}

	if info.IsDir() {
		if err := processDirectory(path); err != nil {
			log.Fatal(err)
		}
	} else {
		if err := processGoxFile(path); err != nil {
			log.Fatal(err)
		}
	}
}

func processDirectory(dir string) error {
	fmt.Printf("处理目录: %s\n", dir)

	return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}

		// 跳过目录
		if d.IsDir() {
			return nil
		}

		// 只处理 .gox.go 文件
		if !strings.HasSuffix(path, ".gox.go") {
			return nil
		}

		return processGoxFile(path)
	})
}

func processGoxFile(goxPath string) error {
	fmt.Printf("处理文件: %s\n", goxPath)

	// 读取源文件
	content, err := os.ReadFile(goxPath)
	if err != nil {
		return fmt.Errorf("读取文件失败 %s: %v", goxPath, err)
	}

	// 生成目标文件路径
	goPath := strings.TrimSuffix(goxPath, ".gox.go") + ".go"

	// 删除已存在的目标文件
	if _, err := os.Stat(goPath); err == nil {
		if err := os.Remove(goPath); err != nil {
			return fmt.Errorf("删除已存在文件失败 %s: %v", goPath, err)
		}
		fmt.Printf("删除已存在文件: %s\n", goPath)
	}

	// 给源文件添加编译忽略指令
	if err := addBuildIgnore(goxPath, string(content)); err != nil {
		return fmt.Errorf("添加编译忽略指令失败: %v", err)
	}

	// 解析并生成目标文件
	p := parser.NewParser()
	goxFile, err := p.ParseFile(goxPath, content)
	if err != nil {
		return fmt.Errorf("解析文件失败: %v", err)
	}

	// 生成Go代码
	generator := parser.NewGenerator()
	generated, err := generator.GenerateFile(goxFile)
	if err != nil {
		return fmt.Errorf("生成代码失败: %v", err)
	}

	// 写入目标文件
	if err := os.WriteFile(goPath, generated, 0644); err != nil {
		return fmt.Errorf("写入文件失败 %s: %v", goPath, err)
	}

	fmt.Printf("生成文件: %s\n", goPath)
	return nil
}

func addBuildIgnore(filePath, content string) error {
	lines := strings.Split(content, "\n")

	// 检查是否已经有编译忽略指令
	hasIgnore := false
	packageIndex := -1

	for i, line := range lines {
		trimmed := strings.TrimSpace(line)
		if strings.HasPrefix(trimmed, "//go:build ignore") ||
			strings.HasPrefix(trimmed, "// +build ignore") {
			hasIgnore = true
		}
		if strings.HasPrefix(trimmed, "package ") {
			packageIndex = i
			break
		}
	}

	// 如果已经有忽略指令，不需要添加
	if hasIgnore {
		return nil
	}

	// 在package行前添加编译忽略指令
	if packageIndex == -1 {
		return fmt.Errorf("找不到package声明")
	}

	newLines := make([]string, 0, len(lines)+3)

	// 添加到package行之前
	newLines = append(newLines, lines[:packageIndex]...)
	newLines = append(newLines, "//go:build ignore")
	newLines = append(newLines, "// +build ignore")
	newLines = append(newLines, "")
	newLines = append(newLines, lines[packageIndex:]...)

	newContent := strings.Join(newLines, "\n")
	return os.WriteFile(filePath, []byte(newContent), 0644)
}
